RDSの自動定期停止をEventBridge SchedulerとCloudFormationで実装してみた
複数のRDSを自動定期停止させたい…。
こんにちは!AWS事業本部のおつまみです。
みなさん!2022年末にリリースされたAWSの新機能「EventBridge Scheduler」使ってますか?
EventBridge Schedulerは、様々なAWSサービスのAPIと連携し、イベントの定期的な実行をスケジュールすることができます。
以前こちらのブログで、RDSを自動定期停止させてみました。
ただしRDSを停止するAPIStopDBInstance
は複数のリソースを指定することができません。
AWS公式のAPIリファレンスを確認すると、Request ParametersのDBInstanceIdentifierはType: String
となっています。
そのため複数のRDSに停止スケジュールを設定したい場合は、EventBridge Schedulerを1つずつ実装する必要があります。
手動で実装するのが面倒なため、今回はCloudFormationテンプレートを作成し、1発で実装できるようにしたいと思います!
構成図
今回はこちらの2つを作成します。
- 停止用のEventBridge Scheduler
- 上記Schedule実行用のIAMロール
やってみた
CloudFormationテンプレート
実行するCloudFormationテンプレートです。
--- AWSTemplateFormatVersion: '2010-09-09' Description: EventBridge Scheduler to stop RDS instance Parameters: InstanceId: Type: String ScheduleStopTime: Type: String Default: "cron(0 20 * * ? *)" ScheduleTimezone: Type: String Default: Japan Resources: ## EventBridgeSchedulerの作成 ScheduleRDSStop: Type: AWS::Scheduler::Schedule Properties: Name: !Sub 'RDS-Stop-${InstanceId}' Description: Stop RDS Instance ScheduleExpression: !Ref ScheduleStopTime ScheduleExpressionTimezone: !Ref ScheduleTimezone FlexibleTimeWindow: Mode: "OFF" State: ENABLED Target: Arn: arn:aws:scheduler:::aws-sdk:rds:stopDBInstance Input: !Sub |- { "DbInstanceIdentifier": "${InstanceId}" } RoleArn: Fn::GetAtt: - SchedulerRDSStopRole - Arn ## EventBridgeSchedulerに紐付けるIAMロールの作成 SchedulerRDSStopRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - scheduler.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: rdsstop PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - rds:StopDBInstance Resource: - "*"
スタック作成時に、こちらのパラメータを指定するだけです。
- 対象インスタンス
- 停止のスケジュール
- タイムゾーン
作成されたリソースを確認
スタック作成完了後、Amazon EventBridgeのスケジュールから作成されたリソースを確認できます。
動作確認
設定したスケジュールで、下準備として用意したRDSが停止されるか見守ります。 今回はテンプレートを使い回し、RDS2台にEventBridge Schedulerを設定しました。
無事、設定した時刻になると起動中→停止中→一時的に停止済みとなりました!
ちょっとハマったところ
EventBridge SchedulerのTarget ServiceArnに指定する[apiAction]
がわからなくハマりました。
CloudFormaitonテンプレートのこの部分です。
ScheduleRDSStop: Type: AWS::Scheduler::Schedule Properties: Name: !Sub 'RDS-Stop-${InstanceId}' Description: Stop RDS Instance ScheduleExpression: !Ref ScheduleStopTime ScheduleExpressionTimezone: !Ref ScheduleTimezone FlexibleTimeWindow: Mode: "OFF" State: ENABLED Target: Arn: arn:aws:scheduler:::aws-sdk:rds:stopDBInstance Input: !Sub |- { "DbInstanceIdentifier": "${InstanceId}" } RoleArn: Fn::GetAtt: - SchedulerRDSStopRole - Arn
公式ドキュメントのユニバーサルターゲットパラーメータ(APIオペレーション)を確認すると、arn:aws:scheduler:::aws-sdk:rds:[apiAction]
と記載されていました。
[apiAction]
に[StopDBInstance]
を指定すると、CloudFormation実行時にこのようなエラーが発生します。
Resource handler returned message: "Invalid request provided: Invalid RequestJson provided. Reason The api StopDBInstance is not valid for the service aws-sdk:rds.
社内で相談したところ、実行するAPIはStopDBInstance
ですが、stopDBInstance
と頭文字を小文字で指定する必要があると分かりました。
AWS SDKの指定では大文字、小文字がしっかり判定されるようです。
ちなみにインプットに指定するRequest ParametersもDBInstanceIdentifier
ではなく、DbInstanceIdentifier
であることに注意です。
最後に
今回はEventBridge SchedulerでRDSの自動定期停止をCloudFormationで実装してみました。
便利なEventBridge SchedulerをCloudFormationと組み合わせることで、さらに便利になりますね!
また弊社が提供するAWS運用簡単サービスopswitchでは、GUI操作で複数のRDS起動・停止をスケジュールできます。 ご興味がある方はこちらのブログをご参考下さい。
最後までお読みいただきありがとうございました!
どなたかのお役に立てれば幸いです。
以上、おつまみ(@AWS11077)でした!
参考
Amazon EventBridge Scheduler resource type reference - AWS CloudFormation
Universal target - EventBridge Scheduler
EventBridge Schedulerを使ってEC2を定期起動・停止するCloudFormationテンプレート | DevelopersIO